package org.kamionowski.supreme.services.search.impl;

import java.util.LinkedList;
import org.apache.commons.lang.ArrayUtils;
import org.kamionowski.supreme.persistence.dao.FileDscDAO;
import org.kamionowski.supreme.persistence.dao.beans.FileSearchBean;
import org.kamionowski.supreme.persistence.entity.FileDsc;
import org.kamionowski.supreme.services.search.SearchFileDscService;
import org.kamionowski.supreme.services.search.tools.FileDscBean;
import org.kamionowski.supreme.services.search.tools.FileType;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * Created by IntelliJ IDEA.
 * User: Marcin Kamionowski
 * Date: 05.04.11
 * Time: 00:35
 */
@Service
@Scope("singleton")
public class SearchFileDscServiceImpl implements SearchFileDscService {

    @Autowired(required = true)
    private FileDscDAO fileDscDAO;

    @Transactional(readOnly = true)
    @Override
    public List<FileDsc> searchFiles(FileDscBean searchBean) {
        FileSearchBean.Builder searchParams = new FileSearchBean.Builder();

        searchParams.setModificationFrom(searchBean.getModificationFrom());
        searchParams.setModificationTo(searchBean.getModificationTo());

        searchParams.setCaseMatch(searchBean.getCaseMatch());

        if (!ArrayUtils.isEmpty(searchBean.getType())) {
            for (FileType fileType : searchBean.getType()) {
                for (String ext : fileType.getExtensions()) {
                    searchParams.addExtension(ext);
                }
            }
        }

        final String expression = searchBean.getExpression();
        for (String token : parseExpression(expression)) {
            searchParams.addToken(token);
        }

        return fileDscDAO.searchFiles(searchParams.build());
    }
    private Pattern quotedTokensPattern = Pattern.compile("\"([^\"]+)\"");
    private Pattern notQuotedTokensPattern = Pattern.compile("([\\w]+)");

    protected String[] parseExpression(String expression) {
        Matcher quotedToken = quotedTokensPattern.matcher(expression);
        List<String> quotedParts = new LinkedList<String>();
        while (quotedToken.find()) {
            final String part = quotedToken.group().replaceAll("\"", "");
            quotedParts.add(part);
        }
        String restOfExpr = quotedToken.replaceAll(" ");
        Matcher notQuotedToken = notQuotedTokensPattern.matcher(restOfExpr);
        List<String> notQuotedParts = new LinkedList<String>();
        while (notQuotedToken.find()) {
            final String part = notQuotedToken.group().replaceAll("\"", "");
            notQuotedParts.add(part);
        }
        String parts[] = quotedParts.toArray(new String[quotedParts.size()]);
        parts = (String[]) ArrayUtils.addAll(parts, notQuotedParts.toArray());
        return parts;
    }
}
